home *** CD-ROM | disk | FTP | other *** search
- /* SDB - token scanning routines */
-
- #include "stdio.h"
- #include "sdbio.h"
-
- int dbv_token; /* current token */
- int dbv_tvalue; /* integer token value */
- char dbv_tstring[STRINGMAX+1]; /* string token value */
- struct ifile *dbv_ifp; /* indirect file context */
- struct macro *dbv_macros; /* macro definitions */
- int dbv_fold; /* case fold alpha comparisons */
-
- static char *iprompt,*cprompt; /* input prompts */
- static char cmdline[LINEMAX+2],*lptr; /* current line and pointer */
- static int atbol; /* flag indicating at bol */
- static int savech; /* lookahead character */
- static int savetkn; /* lookahead token */
- static char *keywords[] = { /* keyword table */
- "ascending",
- "by",
- "char",
- "compress",
- "create",
- "define",
- "delete",
- "descending",
- "exit",
- "export",
- "extract",
- "from",
- "help",
- "insert",
- "import",
- "into",
- "num",
- "print",
- "select",
- "set",
- "show",
- "sort",
- "update",
- "using",
- "where",
- NULL
- };
- static int keytokens[] = { /* token values for each keyword */
- ASCENDING,
- BY,
- CHAR,
- COMPRESS,
- CREATE,
- DEFINE,
- DELETE,
- DESCENDING,
- EXIT,
- EXPORT,
- EXTRACT,
- FROM,
- HELP,
- INSERT,
- IMPORT,
- INTO,
- NUM,
- PRINT,
- SELECT,
- SET,
- SHOW,
- SORT,
- UPDATE,
- USING,
- WHERE,
- NULL
- };
-
- /* db_sinit - initialize the scanner */
- db_sinit()
- {
- /* at beginning of line */
- atbol = TRUE;
-
- /* make the command line null */
- lptr = NULL;
-
- /* no lookahead yet */
- savech = EOS;
- savetkn = NULL;
-
- /* no indirect command files */
- dbv_ifp = NULL;
-
- /* no macros defined */
- dbv_macros = NULL;
-
- /* fold alpha comparisons */
- dbv_fold = TRUE;
- }
-
- /* db_prompt(ip,cp) - initialize prompt strings */
- db_prompt(ip,cp)
- char *ip,*cp;
- {
- /* save initial and continuation prompt strings */
- iprompt = ip;
- cprompt = cp;
- }
-
- /* db_scan(fmt,args) - initiate line scan command parsing */
- db_scan(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
- {
- /* convert the command line and arguments */
- sprintf(cmdline,fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10);
-
- /* start at the beginning of the command line */
- lptr = cmdline;
- iprompt = NULL;
- dbv_ifp = NULL;
-
- /* no lookahead yet */
- savech = EOS;
- savetkn = NULL;
-
- /* fold alpha comparisons */
- dbv_fold = TRUE;
- }
-
- /* db_flush - flush the current input line */
- int db_flush()
- {
- while (savech != '\n')
- if (savech > ' ')
- return (db_ferror(SYNTAX));
- else
- savech = getchx();
-
- savech = EOS;
- atbol = TRUE;
- return (TRUE);
- }
-
- /* db_gline - get a line from the current input */
- char *db_gline(buf)
- char *buf;
- {
- int ch,i;
-
- for (i = 0; (ch = getch()) != '\n' && ch != -1; )
- if (i < LINEMAX)
- buf[i++] = ch;
- else {
- printf("*** line too long ***\nRetype> ");
- i = 0;
- }
- buf[i] = EOS;
-
- return (buf);
- }
-
- /* db_ifile - setup an indirect command file */
- int db_ifile(fname)
- char *fname;
- {
- struct ifile *new_ifp;
-
- if ((new_ifp = malloc(sizeof(struct ifile))) == NULL)
- return (db_ferror(INSMEM));
- else if ((new_ifp->if_fp = fopen(fname,"r")) == NULL) {
- free(new_ifp);
- return (db_ferror(INDFNF));
- }
- new_ifp->if_mtext = NULL;
- new_ifp->if_savech = savech;
- new_ifp->if_lptr = lptr;
- new_ifp->if_next = dbv_ifp;
- dbv_ifp = new_ifp;
-
- /* return successfully */
- return (TRUE);
- }
-
- /* db_kill - kill indirect command file input */
- db_kill()
- {
- struct ifile *old_ifp;
-
- while ((old_ifp = dbv_ifp) != NULL) {
- dbv_ifp = old_ifp->if_next;
- if (old_ifp->if_fp != NULL)
- fclose(old_ifp->if_fp);
- savech = old_ifp->if_savech;
- lptr = old_ifp->if_lptr;
- free(old_ifp);
- }
-
- while (savech != '\n')
- savech = getchx();
-
- savech = EOS;
- savetkn = NULL;
- atbol = TRUE;
- }
-
- /* db_token - return the current input token */
- int db_token()
- {
- struct macro *mptr;
- struct ifile *new_ifp;
-
- /* find a token that's not a macro call */
- while (db_xtoken() == ID) {
-
- /* check for a macro call */
- for (mptr = dbv_macros; mptr != NULL; mptr = mptr->mc_next)
- if (db_scmp(dbv_tstring,mptr->mc_name) == 0) {
- if ((new_ifp = malloc(sizeof(struct ifile))) == NULL)
- printf("*** error expanding macro: %s ***\n",dbv_tstring);
- else {
- new_ifp->if_fp = NULL;
- new_ifp->if_mtext = mptr->mc_mtext->mt_next;
- new_ifp->if_lptr = lptr; lptr = mptr->mc_mtext->mt_text;
- new_ifp->if_savech = savech; savech = EOS;
- new_ifp->if_next = dbv_ifp;
- dbv_ifp = new_ifp;
- }
- savetkn = NULL;
- break;
- }
-
- if (mptr == NULL)
- break;
- }
-
- return (dbv_token);
- }
-
- /* db_xtoken - return the current input token */
- int db_xtoken()
- {
- int ch;
-
- /* check for a saved token */
- if ((dbv_token = savetkn) != NULL)
- return (dbv_token);
-
- /* get the next non-blank character */
- ch = nextch();
-
- /* check type of character */
- if (isalpha(ch)) /* identifier or keyword */
- get_id();
- else if (isdigit(ch)) /* number */
- get_number();
- else if (ch == '"') /* string */
- get_string();
- else if (get_rel()) /* relational operator */
- ;
- else /* single character token */
- dbv_token = getch();
-
- /* save the lookahead token */
- savetkn = dbv_token;
-
- /* return the token */
- return (dbv_token);
- }
-
- /* db_ntoken - get next token (after skipping the current one) */
- int db_ntoken()
- {
- /* get the current token */
- db_token();
-
- /* make sure another is read on next call */
- savetkn = NULL;
-
- /* return the current token */
- return (dbv_token);
- }
-
- /* db_xntoken - get next token (after skipping the current one) */
- int db_xntoken()
- {
- /* get the current token */
- db_xtoken();
-
- /* make sure another is read on next call */
- savetkn = NULL;
-
- /* return the current token */
- return (dbv_token);
- }
-
- /* db_scmp - compare two strings */
- int db_scmp(str1,str2)
- char *str1,*str2;
- {
- if (dbv_fold)
- return (scmp(str1,str2));
- else
- return (strcmp(str1,str2));
- }
-
- /* db_sncmp - compare two strings with a maximum length */
- int db_sncmp(str1,str2,len)
- char *str1,*str2; int len;
- {
- if (dbv_fold)
- return (sncmp(str1,str2,len));
- else
- return (strncmp(str1,str2,len));
- }
-
- /* scmp - compare two strings with alpha case folding */
- static int scmp(str1,str2)
- char *str1,*str2;
- {
- int ch1,ch2;
-
- /* compare each character */
- while (*str1 && *str2) {
-
- /* fold the character from the first string */
- if (isupper(*str1))
- ch1 = tolower(*str1++);
- else
- ch1 = *str1++;
-
- /* fold the character from the second string */
- if (isupper(*str2))
- ch2 = tolower(*str2++);
- else
- ch2 = *str2++;
-
- /* compare the characters */
- if (ch1 != ch2)
- if (ch1 < ch2)
- return (-1);
- else
- return (1);
- }
-
- /* check for strings of different lengths */
- if (*str1 == *str2)
- return (0);
- else if (*str1 == 0)
- return (-1);
- else
- return (1);
- }
-
- /* sncmp - compare two strings with alpha case folding and a maximum length */
- static int sncmp(str1,str2,len)
- char *str1,*str2; int len;
- {
- int ch1,ch2;
-
- /* compare each character */
- while (*str1 && *str2 && len > 0) {
-
- /* fold the character from the first string */
- if (isupper(*str1))
- ch1 = tolower(*str1++);
- else
- ch1 = *str1++;
-
- /* fold the character from the second string */
- if (isupper(*str2))
- ch2 = tolower(*str2++);
- else
- ch2 = *str2++;
-
- /* compare the characters */
- if (ch1 != ch2)
- if (ch1 < ch2)
- return (-1);
- else
- return (1);
-
- /* decrement the string length */
- len--;
- }
-
- /* check for strings of different lengths */
- if (len == 0 || *str1 == *str2)
- return (0);
- else if (*str1 == 0)
- return (-1);
- else
- return (1);
- }
-
- /* get_id - get a keyword or a user identifier */
- static get_id()
- {
- int ch,nchars,i;
-
- /* input letters and digits */
- ch = nextch();
- nchars = 0;
- while (isalpha(ch) || isdigit(ch)) {
- if (nchars < KEYWORDMAX)
- dbv_tstring[nchars++] = ch;
- getch(); ch = thisch();
- }
-
- /* terminate the keyword */
- dbv_tstring[nchars] = EOS;
-
- /* assume its an identifier */
- dbv_token = ID;
-
- /* check for keywords */
- for (i = 0; keywords[i] != NULL; i++)
- if (db_scmp(dbv_tstring,keywords[i]) == 0)
- dbv_token = keytokens[i];
- }
-
- /* get_number - get a number */
- static get_number()
- {
- int ch,ndigits,nodot;
-
- /* read digits and at most one decimal point */
- ch = nextch();
- ndigits = 0; nodot = TRUE;
- while (isdigit(ch) || (nodot && ch == '.')) {
- if (ch == '.')
- nodot = FALSE;
- if (ndigits < NUMBERMAX)
- dbv_tstring[ndigits++] = ch;
- getch(); ch = thisch();
- }
-
- /* terminate the number */
- dbv_tstring[ndigits] = EOS;
-
- /* get the value of the number */
- sscanf(dbv_tstring,"%d",&dbv_tvalue);
-
- /* token is a number */
- dbv_token = NUMBER;
- }
-
- /* get_string - get a string */
- static get_string()
- {
- int ch,nchars;
-
- /* skip the opening quote */
- getch();
-
- /* read characters until a closing quote is found */
- ch = thisch();
- nchars = 0;
- while (ch && ch != '"') {
- if (nchars < STRINGMAX)
- dbv_tstring[nchars++] = ch;
- getch(); ch = thisch();
- }
-
- /* terminate the string */
- dbv_tstring[nchars] = EOS;
-
- /* skip the closing quote */
- getch();
-
- /* token is a string */
- dbv_token = STRING;
- }
-
- /* get_rel - get a relational operator */
- static int get_rel()
- {
- int ch;
-
- switch (ch = nextch()) {
- case '=':
- getch();
- dbv_token = EQL;
- return (TRUE);;
- case '<':
- getch(); ch = nextch();
- if (ch == '>') {
- getch();
- dbv_token = NEQ;
- }
- else if (ch == '=') {
- getch();
- dbv_token = LEQ;
- }
- else
- dbv_token = LSS;
- return (TRUE);;
- case '>':
- getch(); ch = nextch();
- if (ch == '=') {
- getch();
- dbv_token = GEQ;
- }
- else
- dbv_token = GTR;
- return (TRUE);;
- default:
- return (FALSE);
- }
- }
-
- /* getch - get the next character */
- static int getch()
- {
- char fname[STRINGMAX+1];
- int ch,i;
-
- /* return the lookahead character if there is one */
- if (savech != EOS) {
- ch = savech;
- savech = EOS;
- return (ch);
- }
-
- /* get a character */
- ch = getchx();
-
- /* skip spaces at the beginning of a command */
- if (atbol && iprompt != NULL)
- while (ch <= ' ')
- ch = getchx();
-
- /* use continuation prompt next time */
- iprompt = NULL;
-
- /* check for indirect command file */
- while (ch == '@') {
- for (i = 0; (savech = getchx()) > ' '; )
- if (i < STRINGMAX)
- fname[i++] = savech;
- fname[i] = 0;
- if (db_ifile(fname) != TRUE)
- printf("*** error opening command file: %s ***\n",fname);
- ch = getchx();
- }
-
- /* return the character */
- return (ch);
- }
-
- /* getchx - get the next character */
- static int getchx()
- {
- struct ifile *old_ifp;
- int ch;
-
- /* check for input from buffer */
- if (lptr != NULL) {
- while (*lptr == EOS)
- if (dbv_ifp != NULL)
- if (dbv_ifp->if_mtext == NULL) {
- old_ifp = dbv_ifp;
- ch = dbv_ifp->if_savech; savech = EOS;
- lptr = dbv_ifp->if_lptr;
- dbv_ifp = dbv_ifp->if_next;
- free(old_ifp);
- if (ch != EOS)
- return (ch);
- if (lptr == NULL)
- break;
- }
- else {
- lptr = dbv_ifp->if_mtext->mt_text;
- dbv_ifp->if_mtext = dbv_ifp->if_mtext->mt_next;
- }
- else
- return (EOS);
-
- if (lptr != NULL)
- return (*lptr++);
- }
-
- /* print prompt if necessary */
- if (atbol && dbv_ifp == NULL) { /*dns*/
- if (iprompt != NULL)
- printf("%s",iprompt);
- else if (cprompt != NULL)
- printf("%s",cprompt);
- #ifdef Lattice
- fflush(stdout); /*dns*/
- #endif
- } /*dns*/
-
- if (dbv_ifp == NULL)
- if ((ch = getcx(stdin)) == '\n')
- atbol = TRUE;
- else
- atbol = FALSE;
- else {
- if ((ch = getcx(dbv_ifp->if_fp)) == -1) {
- old_ifp = dbv_ifp;
- ch = dbv_ifp->if_savech; savech = EOS;
- lptr = dbv_ifp->if_lptr;
- dbv_ifp = dbv_ifp->if_next;
- fclose(old_ifp->if_fp);
- free(old_ifp);
- }
- }
-
- /* return the character */
- return (ch);
- }
-
- /* thisch - get the current character */
- static int thisch()
- {
- /* get a lookahead character */
- if (savech == EOS)
- savech = getch();
-
- /* return lookahead character */
- return (savech);
- }
-
- /* nextch - get the next non-blank character */
- static int nextch()
- {
- int ch;
-
- /* skip blank characters */
- while ((ch = thisch()) <= ' ' && ch != EOS)
- getch();
-
- /* return the first non-blank */
- return (ch);
- }
-
- (textline)+1)) == NULL) {
- mc_free(mptr);
- return (db_ferror(INSMEM));
- }
-